Daten einlesen und Dataframe erstellen
# List files in folder "Data"
files <- list.files(path="./Data/", pattern=NULL, all.files=FALSE, full.names=TRUE)
# Create Dataframe with all csv from years 2015-2019
df <- ldply(.data = files, .fun = read.csv)
#View(df)
Hier zählen wir, wie oft das Heim - und Auswärtsteam zur Halb - und
Vollzeit gewinnen oder ob das Spiel unentschieden ist.
A = Auswärtsteam gewinnt
D = Unentschieden
H = Heimteam gewinnt
# Create dataframe for halftime & fulltime results and count frequency
df_htr <- df %>% count(HTR)
df_ftr <- df %>% count(FTR)
# Halftime
df_htr
# Fulltime
df_ftr
# Create dataframe with halftime & fulltime result frequency
df_results <- data.frame(c("Away win", "Draw", "Home win"), c(df_htr$n), c(df_ftr$n))
# Rename column headers
col_headings <- c('Result','Halftime','Fulltime')
names(df_results) <- col_headings
df_results
# Plot grouped bar chart to visualize halftime & fulltime results
fig <- plot_ly(
df_results, x = ~Result, y = ~Halftime, type = 'bar', name = 'Halftime Score') %>%
add_trace(y = ~Fulltime, name = 'Fulltime Score') %>%
layout(yaxis = list(title = 'Amount'),
barmode = 'group',
width = 600, height = 500)
Warning: Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()
fig
# Merge HTR & FTR to new column 'result'
df$result <- paste(df$HTR, df$FTR)
# Example: H H = home team is winning at halftime and also wins the game at fulltime
df[,"result", drop=FALSE]
# Plot all different game progresses and their amount
df_count_results <- df %>%
count(result)
df_count_results %>%
mutate(result = fct_reorder(result, n, .desc = TRUE)) %>%
plot_ly(x = ~result, y = ~n, text = ~n, textposition = 'auto') %>%
add_bars() %>%
layout(xaxis = list(title = "Game Progress"),
yaxis = list(title = "Amount"),
title = "How are the different game progresses distributed?",
width = 800, height = 500)
Warning: Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()
Hier wollen wir herausfinden, wie wahrscheinlich die 9 möglichen
Spielausgängen sind bevor das Spiel überhaupt beginnt.
# Group by game outcome & calculate probability of all outcomes
df_count_results_prob <- df %>%
group_by(result) %>%
summarise(count_result = round(n() / nrow(df) * 100, digits = 2))
# Plot all different game progresses and their probability
df_count_results_prob %>%
mutate(result = fct_reorder(result, count_result, .desc = TRUE)) %>%
plot_ly(x = ~result, y = ~count_result, text = ~count_result, textposition = 'auto') %>%
add_bars() %>%
layout(xaxis = list(title = "Game Progress"),
yaxis = list(title = "Probability of Game Progress (%)"),
title = "How are the different game progresses distributed?",
width = 800, height = 500)
Warning: Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()
# Group by game outcome & calculate probability of all outcomes
df_count_results <- df %>%
group_by(result) %>%
summarise(count_result = round(n() / nrow(df) * 100, digits = 2))
df_count_results %>%
plot_ly(labels = ~result, values = ~count_result) %>%
add_pie(hole = 0.4, color = I("white")) %>%
layout(xaxis = list(title = "Game Progress"),
yaxis = list(title = "Probability %"),
title = "What is the probability of each game progress?")
# Calculate probability
calc_prob <- function(df1, df2) {
prob <- round((100 / nrow(df1) * nrow(df2)), digits = 2)
return(prob)
}
# Filter home teams winning at halftime
df_ht_home <- df %>%
filter(HTR == "H")
# Filter home teams winning at halftime & fulltime
df_ft_home <- df_ht_home %>%
filter(FTR == "H")
home_win_prob <- calc_prob(df_ht_home, df_ft_home)
cat("Probability that the home team wins the game if they are leading at half time: ", home_win_prob, "%")
Probability that the home team wins the game if they are leading at half time: 82.55 %
# Filter away teams winning at halftime
df_ht_away <- df %>%
filter(HTR == "A")
# Filter away teams winning at halftime & fulltime
df_ft_away <- df_ht_away %>%
filter(FTR == "A")
away_win_prob <- calc_prob(df_ht_away, df_ft_away)
cat("Probability that the away team wins the game if they are leading at half time: ", away_win_prob, "%")
Probability that the away team wins the game if they are leading at half time: 72.03 %
# Filter draw at halftime
df_ht_draw <- df %>%
filter(HTR == "D")
# Filter draw at halftime & fulltime
df_ft_draw <- df_ht_draw %>%
filter(FTR == "D")
draw_prob <- calc_prob(df_ht_draw, df_ft_draw)
cat("Probability that the game ends in a draw if the halftime result is also a draw: ", draw_prob, "%")
Probability that the game ends in a draw if the halftime result is also a draw: 36.45 %
# Filter draw at halftime & the home team winning at fulltime
df_ht_draw_ft_home_win <- df_ht_draw %>%
filter(FTR == "H")
home_win_after_ht_draw_prob <- calc_prob(df_ht_draw, df_ht_draw_ft_home_win)
cat("Probability that the home team wins if the halftime result is a draw: ", home_win_after_ht_draw_prob, "%")
Probability that the home team wins if the halftime result is a draw: 38.03 %
LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXphdGlvbiBtaXQgUGxvdGx5Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KRGFzIFppZWwgaXN0IGVzLCBhdXMgZGVtIERhdGFjYW1wIERhdGVuc2F0eiBbU29jY2VyIERhdGFdKGh0dHBzOi8vYXBwLmRhdGFjYW1wLmNvbS93b3Jrc3BhY2UvZGF0YXNldHMvZGF0YXNldC1weXRob24tc29jY2VyKSwgd2VsY2hlciBEYXRlbiBhdXMgZGVyIGjDtmNoc3RlbiBlbmdsaXNjaGVuIEZ1c3NiYWxsZGl2aXNpb24gYmVpbmhhbHRldCwgZm9sZ2VuZGUgRnJhZ2VzdGVsbHVuZyAvIEh5cG90aGVzZSB6dSBiZWFudHdvcnRlbjoNCg0KDQojIyMgRGllIE1hbnNjaGFmdCwgZGllIHp1ciBIYWxiemVpdCB2b3JuZSBsaWVndCwgZ2V3aW5udCBtaXQgZWluZXIgQ2hhbmNlIHZvbiBtaW5kZXN0ZW5zIDc1JSBkYXMgU3BpZWwuIEZhbGxzIHp1ciBIYWxiemVpdCB1bmVudHNjaGllZGVuIGlzdCwgZ2V3aW5udCBlaGVyIGRhcyBIZWltdGVhbSBtaXQgZWluZXIgQ2hhbmNlIHZvbiBtaW5kZXN0ZW5zIDMzLjQlLg0KDQoNCkFscyBFaW5mw7xocnVuZyB3ZXJkZW4gd2lyIGF1ZiBEYXRhY2FtcCBmb2xnZW5kZSBLdXJzZSBkdXJjaGdlaGVuOg0KDQotIFtJbnRlcmFjdGl2ZSBEYXRhIFZpc3VhbGl6YXRpb24gd2l0aCBwbG90bHldKGh0dHBzOi8vYXBwLmRhdGFjYW1wLmNvbS9sZWFybi9jb3Vyc2VzL2ludGVyYWN0aXZlLWRhdGEtdmlzdWFsaXphdGlvbi13aXRoLXBsb3RseS1pbi1yKQ0KDQotIFtJbnRlcm1lZGlhdGUgSW50ZXJhY3RpdmUgRGF0YSBWaXN1YWxpemF0aW9uIHdpdGggcGxvdGx5XShodHRwczovL2FwcC5kYXRhY2FtcC5jb20vbGVhcm4vY291cnNlcy9pbnRlcmFjdGl2ZS1kYXRhLXZpc3VhbGl6YXRpb24td2l0aC1wbG90bHktaW4tcikNCg0KDQpgYGB7cn0NCiMgQmlibGlvdGhla2VuIGltcG9ydGllcmVuDQpsaWJyYXJ5KCJwbG90bHkiKQ0KbGlicmFyeSgicGx5ciIpDQpsaWJyYXJ5KCJkcGx5ciIpDQpsaWJyYXJ5KCJmb3JjYXRzIikNCmxpYnJhcnkoIlJDb2xvckJyZXdlciIpDQpgYGANCg0KIyMjIERhdGVuIGVpbmxlc2VuIHVuZCBEYXRhZnJhbWUgZXJzdGVsbGVuDQoNCmBgYHtyfQ0KIyBMaXN0IGZpbGVzIGluIGZvbGRlciAiRGF0YSINCmZpbGVzIDwtIGxpc3QuZmlsZXMocGF0aD0iLi9EYXRhLyIsIHBhdHRlcm49TlVMTCwgYWxsLmZpbGVzPUZBTFNFLCBmdWxsLm5hbWVzPVRSVUUpDQoNCiMgQ3JlYXRlIERhdGFmcmFtZSB3aXRoIGFsbCBjc3YgZnJvbSB5ZWFycyAyMDE1LTIwMTkNCmRmIDwtIGxkcGx5KC5kYXRhID0gZmlsZXMsIC5mdW4gPSByZWFkLmNzdikNCg0KI1ZpZXcoZGYpDQpgYGANCg0KSGllciB6w6RobGVuIHdpciwgd2llIG9mdCBkYXMgSGVpbSAtIHVuZCBBdXN3w6RydHN0ZWFtIHp1ciBIYWxiIC0gdW5kIFZvbGx6ZWl0IGdld2lubmVuIG9kZXIgb2IgZGFzIFNwaWVsIHVuZW50c2NoaWVkZW4gaXN0Lg0KDQotIEEgPSBBdXN3w6RydHN0ZWFtIGdld2lubnQNCg0KLSBEID0gVW5lbnRzY2hpZWRlbg0KDQotIEggPSBIZWltdGVhbSBnZXdpbm50DQoNCmBgYHtyfQ0KIyBDcmVhdGUgZGF0YWZyYW1lIGZvciBoYWxmdGltZSAmIGZ1bGx0aW1lIHJlc3VsdHMgYW5kIGNvdW50IGZyZXF1ZW5jeSANCmRmX2h0ciA8LSBkZiAlPiUgY291bnQoSFRSKQ0KZGZfZnRyIDwtIGRmICU+JSBjb3VudChGVFIpDQoNCiMgSGFsZnRpbWUNCmRmX2h0cg0KIyBGdWxsdGltZQ0KZGZfZnRyDQpgYGANCg0KYGBge3J9DQojIENyZWF0ZSBkYXRhZnJhbWUgd2l0aCBoYWxmdGltZSAmIGZ1bGx0aW1lIHJlc3VsdCBmcmVxdWVuY3kNCmRmX3Jlc3VsdHMgPC0gZGF0YS5mcmFtZShjKCJBd2F5IHdpbiIsICJEcmF3IiwgIkhvbWUgd2luIiksIGMoZGZfaHRyJG4pLCBjKGRmX2Z0ciRuKSkNCg0KIyBSZW5hbWUgY29sdW1uIGhlYWRlcnMNCmNvbF9oZWFkaW5ncyA8LSBjKCdSZXN1bHQnLCdIYWxmdGltZScsJ0Z1bGx0aW1lJykNCm5hbWVzKGRmX3Jlc3VsdHMpIDwtIGNvbF9oZWFkaW5ncw0KDQpkZl9yZXN1bHRzDQpgYGANCmBgYHtyfQ0KIyBQbG90IGdyb3VwZWQgYmFyIGNoYXJ0IHRvIHZpc3VhbGl6ZSBoYWxmdGltZSAmIGZ1bGx0aW1lIHJlc3VsdHMNCmZpZyA8LSBwbG90X2x5KA0KICBkZl9yZXN1bHRzLCB4ID0gflJlc3VsdCwgeSA9IH5IYWxmdGltZSwgdHlwZSA9ICdiYXInLCBuYW1lID0gJ0hhbGZ0aW1lIFNjb3JlJykgJT4lIA0KICBhZGRfdHJhY2UoeSA9IH5GdWxsdGltZSwgbmFtZSA9ICdGdWxsdGltZSBTY29yZScpICU+JQ0KICBsYXlvdXQoeWF4aXMgPSBsaXN0KHRpdGxlID0gJ0Ftb3VudCcpLCANCiAgICAgICAgIGJhcm1vZGUgPSAnZ3JvdXAnLA0KICAgICAgICAgd2lkdGggPSA2MDAsIGhlaWdodCA9IDUwMCkNCg0KZmlnDQpgYGANCg0KDQpgYGB7cn0NCiMgTWVyZ2UgSFRSICYgRlRSIHRvIG5ldyBjb2x1bW4gJ3Jlc3VsdCcNCmRmJHJlc3VsdCA8LSBwYXN0ZShkZiRIVFIsIGRmJEZUUikNCg0KIyBFeGFtcGxlOiBIIEggPSBob21lIHRlYW0gaXMgd2lubmluZyBhdCBoYWxmdGltZSBhbmQgYWxzbyB3aW5zIHRoZSBnYW1lIGF0IGZ1bGx0aW1lDQoNCmRmWywicmVzdWx0IiwgZHJvcD1GQUxTRV0NCmBgYA0KDQpgYGB7cn0NCiMgUGxvdCBhbGwgZGlmZmVyZW50IGdhbWUgcHJvZ3Jlc3NlcyBhbmQgdGhlaXIgYW1vdW50DQpkZl9jb3VudF9yZXN1bHRzIDwtIGRmICU+JQ0KICBjb3VudChyZXN1bHQpDQogIA0KZGZfY291bnRfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKHJlc3VsdCA9IGZjdF9yZW9yZGVyKHJlc3VsdCwgbiwgLmRlc2MgPSBUUlVFKSkgJT4lDQogIHBsb3RfbHkoeCA9IH5yZXN1bHQsIHkgPSB+biwgdGV4dCA9IH5uLCB0ZXh0cG9zaXRpb24gPSAnYXV0bycpICU+JQ0KICBhZGRfYmFycygpICU+JQ0KICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gIkdhbWUgUHJvZ3Jlc3MiKSwNCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJBbW91bnQiKSwNCiAgICAgICAgIHRpdGxlID0gIkhvdyBhcmUgdGhlIGRpZmZlcmVudCBnYW1lIHByb2dyZXNzZXMgZGlzdHJpYnV0ZWQ/IiwNCiAgICAgICAgIHdpZHRoID0gODAwLCBoZWlnaHQgPSA1MDApDQpgYGANCkhpZXIgd29sbGVuIHdpciBoZXJhdXNmaW5kZW4sIHdpZSB3YWhyc2NoZWlubGljaCBkaWUgOSBtw7ZnbGljaGVuIFNwaWVsYXVzZ8OkbmdlbiBzaW5kIGJldm9yIGRhcyBTcGllbCDDvGJlcmhhdXB0IGJlZ2lubnQuDQpgYGB7cn0NCiMgR3JvdXAgYnkgZ2FtZSBvdXRjb21lICYgY2FsY3VsYXRlIHByb2JhYmlsaXR5IG9mIGFsbCBvdXRjb21lcw0KZGZfY291bnRfcmVzdWx0c19wcm9iIDwtIGRmICU+JSANCiAgZ3JvdXBfYnkocmVzdWx0KSAlPiUgDQogIHN1bW1hcmlzZShjb3VudF9yZXN1bHQgPSByb3VuZChuKCkgLyBucm93KGRmKSAqIDEwMCwgZGlnaXRzID0gMikpDQoNCiMgUGxvdCBhbGwgZGlmZmVyZW50IGdhbWUgcHJvZ3Jlc3NlcyBhbmQgdGhlaXIgcHJvYmFiaWxpdHkNCmRmX2NvdW50X3Jlc3VsdHNfcHJvYiAlPiUNCiAgbXV0YXRlKHJlc3VsdCA9IGZjdF9yZW9yZGVyKHJlc3VsdCwgY291bnRfcmVzdWx0LCAuZGVzYyA9IFRSVUUpKSAlPiUNCiAgcGxvdF9seSh4ID0gfnJlc3VsdCwgeSA9IH5jb3VudF9yZXN1bHQsIHRleHQgPSB+Y291bnRfcmVzdWx0LCB0ZXh0cG9zaXRpb24gPSAnYXV0bycpICU+JQ0KICBhZGRfYmFycygpICU+JQ0KICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gIkdhbWUgUHJvZ3Jlc3MiKSwNCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJQcm9iYWJpbGl0eSBvZiBHYW1lIFByb2dyZXNzICglKSIpLA0KICAgICAgICAgdGl0bGUgPSAiSG93IGFyZSB0aGUgZGlmZmVyZW50IGdhbWUgcHJvZ3Jlc3NlcyBkaXN0cmlidXRlZD8iLA0KICAgICAgICAgd2lkdGggPSA4MDAsIGhlaWdodCA9IDUwMCkNCmBgYA0KDQpgYGB7cn0NCiMgR3JvdXAgYnkgZ2FtZSBvdXRjb21lICYgY2FsY3VsYXRlIHByb2JhYmlsaXR5IG9mIGFsbCBvdXRjb21lcw0KZGZfY291bnRfcmVzdWx0cyA8LSBkZiAlPiUgDQogIGdyb3VwX2J5KHJlc3VsdCkgJT4lIA0KICBzdW1tYXJpc2UoY291bnRfcmVzdWx0ID0gcm91bmQobigpIC8gbnJvdyhkZikgKiAxMDAsIGRpZ2l0cyA9IDIpKQ0KDQpkZl9jb3VudF9yZXN1bHRzICU+JQ0KICBwbG90X2x5KGxhYmVscyA9IH5yZXN1bHQsIHZhbHVlcyA9IH5jb3VudF9yZXN1bHQpICU+JQ0KICBhZGRfcGllKGhvbGUgPSAwLjQsIGNvbG9yID0gSSgid2hpdGUiKSkgJT4lDQogIGxheW91dCh4YXhpcyA9IGxpc3QodGl0bGUgPSAiR2FtZSBQcm9ncmVzcyIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlByb2JhYmlsaXR5ICUiKSwNCiAgICAgICAgIHRpdGxlID0gIldoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGVhY2ggZ2FtZSBwcm9ncmVzcz8iKQ0KYGBgDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHByb2JhYmlsaXR5IGJldHdlZW4gaGFsZnRpbWUgJiBmdWxsdGltZSBhd2F5IC8gZHJhdyAvIGhvbWUgcmVzdWx0cw0KY2FsY19wcm9iIDwtIGZ1bmN0aW9uKGRmMSwgZGYyKSB7DQogIHByb2IgPC0gcm91bmQoKDEwMCAvIG5yb3coZGYxKSAqIG5yb3coZGYyKSksIGRpZ2l0cyA9IDIpDQogIHJldHVybihwcm9iKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgaG9tZSB0ZWFtcyB3aW5uaW5nIGF0IGhhbGZ0aW1lDQpkZl9odF9ob21lIDwtIGRmICU+JSANCiAgZmlsdGVyKEhUUiA9PSAiSCIpDQoNCiMgRmlsdGVyIGhvbWUgdGVhbXMgd2lubmluZyBhdCBoYWxmdGltZSAmIGZ1bGx0aW1lDQpkZl9mdF9ob21lIDwtIGRmX2h0X2hvbWUgJT4lIA0KICBmaWx0ZXIoRlRSID09ICJIIikNCg0KaG9tZV93aW5fcHJvYiA8LSBjYWxjX3Byb2IoZGZfaHRfaG9tZSwgZGZfZnRfaG9tZSkNCg0KY2F0KCJQcm9iYWJpbGl0eSB0aGF0IHRoZSBob21lIHRlYW0gd2lucyB0aGUgZ2FtZSBpZiB0aGV5IGFyZSBsZWFkaW5nIGF0IGhhbGYgdGltZTogIiwgaG9tZV93aW5fcHJvYiwgIiUiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgYXdheSB0ZWFtcyB3aW5uaW5nIGF0IGhhbGZ0aW1lDQpkZl9odF9hd2F5IDwtIGRmICU+JSANCiAgZmlsdGVyKEhUUiA9PSAiQSIpDQoNCiMgRmlsdGVyIGF3YXkgdGVhbXMgd2lubmluZyBhdCBoYWxmdGltZSAmIGZ1bGx0aW1lDQpkZl9mdF9hd2F5IDwtIGRmX2h0X2F3YXkgJT4lIA0KICBmaWx0ZXIoRlRSID09ICJBIikNCg0KYXdheV93aW5fcHJvYiA8LSBjYWxjX3Byb2IoZGZfaHRfYXdheSwgZGZfZnRfYXdheSkNCg0KY2F0KCJQcm9iYWJpbGl0eSB0aGF0IHRoZSBhd2F5IHRlYW0gd2lucyB0aGUgZ2FtZSBpZiB0aGV5IGFyZSBsZWFkaW5nIGF0IGhhbGYgdGltZTogIiwgYXdheV93aW5fcHJvYiwgIiUiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgZHJhdyBhdCBoYWxmdGltZQ0KZGZfaHRfZHJhdyA8LSBkZiAlPiUgDQogIGZpbHRlcihIVFIgPT0gIkQiKQ0KDQojIEZpbHRlciBkcmF3IGF0IGhhbGZ0aW1lICYgZnVsbHRpbWUNCmRmX2Z0X2RyYXcgPC0gZGZfaHRfZHJhdyAlPiUgDQogIGZpbHRlcihGVFIgPT0gIkQiKQ0KDQpkcmF3X3Byb2IgPC0gY2FsY19wcm9iKGRmX2h0X2RyYXcsIGRmX2Z0X2RyYXcpDQoNCmNhdCgiUHJvYmFiaWxpdHkgdGhhdCB0aGUgZ2FtZSBlbmRzIGluIGEgZHJhdyBpZiB0aGUgaGFsZnRpbWUgcmVzdWx0IGlzIGFsc28gYSBkcmF3OiAiLCBkcmF3X3Byb2IsICIlIikNCmBgYA0KDQpgYGB7cn0NCiMgRmlsdGVyIGRyYXcgYXQgaGFsZnRpbWUgJiB0aGUgaG9tZSB0ZWFtIHdpbm5pbmcgYXQgZnVsbHRpbWUNCmRmX2h0X2RyYXdfZnRfaG9tZV93aW4gPC0gZGZfaHRfZHJhdyAlPiUNCiAgZmlsdGVyKEZUUiA9PSAiSCIpDQoNCmhvbWVfd2luX2FmdGVyX2h0X2RyYXdfcHJvYiA8LSBjYWxjX3Byb2IoZGZfaHRfZHJhdywgZGZfaHRfZHJhd19mdF9ob21lX3dpbikNCg0KY2F0KCJQcm9iYWJpbGl0eSB0aGF0IHRoZSBob21lIHRlYW0gd2lucyBpZiB0aGUgaGFsZnRpbWUgcmVzdWx0IGlzIGEgZHJhdzogIiwgaG9tZV93aW5fYWZ0ZXJfaHRfZHJhd19wcm9iLCAiJSIpDQpgYGANCiMjIyBCZXN0w6R0aWd1bmcgZGVyIEh5cG90aGVzZQ0KDQpTb21pdCBrw7ZubmVuIHdpciBhdXMgZGllIDIgV2FocnNjaGVpbmxpY2hrZWl0ZW4gImhvbWVfd2luX3Byb2IiIHVuZCAiYXdheV93aW5fcHJvYiIgdW5zZXJlIEh5cG90aGVzZSB3aWUgZm9sZ3QgYmVzdMOkdGlnZW46IA0KDQpgYGB7cn0NCiMgUHJvYmFiaWxpdHkgdGhhdCB0aGUgdGVhbSB3aW5uaW5nIGF0IGhhbGYgdGltZSB3aW5zIHRoZSBnYW1lDQpodF9mdF93aW5fcHJvYiA8LSByb3VuZCgoKGhvbWVfd2luX3Byb2IgKiBucm93KGRmX2Z0X2hvbWUpKSArIChhd2F5X3dpbl9wcm9iICogbnJvdyhkZl9mdF9hd2F5KSkpIC8gKG5yb3coZGZfZnRfaG9tZSkgKyBucm93KGRmX2Z0X2F3YXkpKSwgZGlnaXRzID0gMikNCg0KY2F0KCJQcm9iYWJpbGl0eSB0aGF0IHRoZSB0ZWFtIGxlYWRpbmcgYXQgaGFsZiB0aW1lIHdpbnMgdGhlIGVudGlyZSBnYW1lOiAiLCBodF9mdF93aW5fcHJvYiwgIiUiKQ0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0K